{Object Pascal Demonstration Program}
{by Rich Siegel}
{©1988 Symantec Corporation}

{This unit contains "InstallDefProc", which is a generic routine that makes it possible to have}
{custom definition routines be installed as part of the program, rather than requiring the programmer}
{to build and debug the code resources separately.}

{InstallDefProc does its thing by installing a "fake" defproc resource of the desired type and ID in}
{the resource file designated by "dpPath". This resource contains a JMP instruction, followed by}
{a destination for the JMP. If the resource doesn't exist, it's created and added to the file; if it's}
{already in the desired file, it's simply loaded. Either way, the procedure's address (passed in}
{"dpAddr") is set up in the handle, and the handle is made nonpurgeable.}

Unit UDPInstall;
Interface
	Procedure InstallDefProc (dpPath: Integer;
									dpType: ResType;
									dpID: Integer;
									dpAddr: Ptr);

Implementation
	Type
		JmpRecord = Record
				jmpInstr: Integer;
				jmpAddr: Ptr;
			End;
		JmpPtr = ^JmpRecord;
		JmpHandle = ^JmpPtr;

	Procedure InstallDefProc;
		Var
			jH: JmpHandle;

			savePath: Integer;

	Begin
		savePath := CurResFile;		{preserve the resource file currently in use}
		UseResFile(dpPath);				{look only in the specified path}

		jH := JmpHandle(GetResource(dpType, dpID)); {try to get the dummy defproc}

		If jH = Nil Then		{if it's not there, create a handle and add it.}
			Begin
				jh := JmpHandle(NewHandle(SizeOf(JmpRecord)));
				AddResource(Handle(jh), dpType, dpID, '');
			End;
		jh^^.jmpInstr := $4EF9;			{Jump to absolute address}
		jh^^.jmpAddr := dpAddr;		{the address to which we jump}

		HNoPurge(Handle(jH));			{make the defproc nonpurgeable}

		UseResFile(savePath);			{restore the resource file chain.}
	End;
End.